﻿using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;


namespace test3d
{
  /// <summary>
  /// Interaction logic for MainWindow.xaml
  /// </summary>
  public partial class MainWindow: Window
  {
    static private Vector3D CalculateNormal( Point3D p0, Point3D p1, Point3D p2 )
    {
      Vector3D v0 = new Vector3D(
          p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z );
      Vector3D v1 = new Vector3D(
          p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z );
      return Vector3D.CrossProduct( v0, v1 );
    }
    static private Model3DGroup CreateTriangleModel( Point3D p0, Point3D p1, Point3D p2, MaterialGroup materialgroup )
    {
      MeshGeometry3D mesh = new MeshGeometry3D();
      mesh.Positions.Add( p0 );
      mesh.Positions.Add( p1 );
      mesh.Positions.Add( p2 );
      mesh.TriangleIndices.Add( 0 );
      mesh.TriangleIndices.Add( 1 );
      mesh.TriangleIndices.Add( 2 );
      mesh.TextureCoordinates = ( (PointCollection)new PointCollectionConverter().ConvertFromString( "0,0 0,1 1,1 1,0" ) );
      //TODO: tamto texture coordinates powinny zostac przeniesione
      GeometryModel3D model = new GeometryModel3D(
          mesh, materialgroup );
      Model3DGroup group = new Model3DGroup();
      group.Children.Add( model );
      return group;
    }
    static private Model3DGroup CreateSquareModel( Point3D p0, Point3D p1, Point3D p2, Point3D p3, MaterialGroup materialgroup )
    {
      MeshGeometry3D mesh = new MeshGeometry3D();
      mesh.Positions.Add( p0 );
      mesh.Positions.Add( p1 );
      mesh.Positions.Add( p2 );
      mesh.Positions.Add( p3 );
      // 0,1,2,0,2,3
      mesh.TriangleIndices.Add( 2 );
      mesh.TriangleIndices.Add( 1 );
      mesh.TriangleIndices.Add( 0 );
      mesh.TriangleIndices.Add( 3 );
      mesh.TriangleIndices.Add( 2 );
      mesh.TriangleIndices.Add( 0 );
      mesh.TextureCoordinates = ( (PointCollection)new PointCollectionConverter().ConvertFromString( "0,1  0,0 1,0  1,1 " ) );
      //TODO: tamto texture coordinates powinny zostac przeniesione
      GeometryModel3D model = new GeometryModel3D(
          mesh, materialgroup );
      Model3DGroup group = new Model3DGroup();
      group.Children.Add( model );
      return group;
    }
    static private Model3DGroup CreateCubeModel3DGroup
      ( double X, double Y, double Z,
      double sizeX, double sizeY, double sizeZ, MaterialGroup mg )
    {
      Model3DGroup cube = new Model3DGroup();
      Point3D p0 = new Point3D( X - sizeX / 2, Y - sizeY / 2, Z - sizeZ / 2 );
      Point3D p1 = new Point3D( X + sizeX / 2, Y - sizeY / 2, Z - sizeZ / 2 );
      Point3D p2 = new Point3D( X + sizeX / 2, Y - sizeY / 2, Z + sizeZ / 2 );
      Point3D p3 = new Point3D( X - sizeX / 2, Y - sizeY / 2, Z + sizeZ / 2 );
      Point3D p4 = new Point3D( X - sizeX / 2, Y + sizeY / 2, Z - sizeZ / 2 );
      Point3D p5 = new Point3D( X + sizeX / 2, Y + sizeY / 2, Z - sizeZ / 2 );
      Point3D p6 = new Point3D( X + sizeX / 2, Y + sizeY / 2, Z + sizeZ / 2 );
      Point3D p7 = new Point3D( X - sizeX / 2, Y + sizeY / 2, Z + sizeZ / 2 );

      //front side triangles
      cube.Children.Add( CreateSquareModel( p3, p2, p1,p0,mg ) );
      //right side triangles
      cube.Children.Add( CreateSquareModel( p4, p5, p6,p7, mg ) );
      //back side triangles
      cube.Children.Add( CreateSquareModel( p2, p3, p7,p6, mg ) );
      //left side triangles
      cube.Children.Add( CreateSquareModel( p0, p1, p5,p4, mg ) );
      //top side triangles
      cube.Children.Add( CreateSquareModel( p1, p2, p6,p5, mg ) );
      //bottom side triangles
      cube.Children.Add( CreateSquareModel( p7, p3, p0,p4, mg ) );
      return cube;
    }

    static private Model3DGroup CreateTetraederModel3DGroup
  ( double X, double Y, double Z,
  double sizeX, double sizeY, double sizeZ, MaterialGroup mg )
    {
      Model3DGroup tetraeder = new Model3DGroup();
      Point3D p0 = new Point3D( X - sizeX / 2, Y - sizeY / 2, Z - sizeZ / 2 );
      Point3D p2 = new Point3D( X + sizeX / 2, Y - sizeY / 2, Z + sizeZ / 2 );
      Point3D p5 = new Point3D( X + sizeX / 2, Y + sizeY / 2, Z - sizeZ / 2 );
      Point3D p7 = new Point3D( X - sizeX / 2, Y + sizeY / 2, Z + sizeZ / 2 );
      tetraeder.Children.Add( CreateTriangleModel( p0, p5, p7,mg ) );
      tetraeder.Children.Add( CreateTriangleModel( p0, p2, p5,mg ) );
      tetraeder.Children.Add( CreateTriangleModel( p0, p7, p2,mg ) );
      tetraeder.Children.Add( CreateTriangleModel( p5, p2, p7,mg ) );
      return tetraeder;
    }

    static private ModelVisual3D CreateCubeModel3DModel( double X, double Y, double Z,
double sizeX, double sizeY, double sizeZ, MaterialGroup mg )
    {

      Model3DGroup cube = CreateCubeModel3DGroup( X, Y, Z, sizeX, sizeY, sizeZ,mg );
      ModelVisual3D model = new ModelVisual3D();
      model.Content = cube;
      return model;
    }
    public MainWindow()
    {
      InitializeComponent();

      //mesh.TextureCoordinates = ( (PointCollection)new PointCollectionConverter().ConvertFromString( "0,0 0,1 1,1 1,0" ) );
      //LinearGradientBrush myBrush = new LinearGradientBrush();
      //myBrush.GradientStops.Add( new GradientStop( Colors.Yellow, 0.0 ) );
      //myBrush.GradientStops.Add( new GradientStop( Colors.Red,0.5) );
      //myBrush.GradientStops.Add( new GradientStop( Colors.Blue, 1 ) );
      //Material material = new DiffuseMaterial( myBrush );


      //TextBlock textblock = new TextBlock( new Run( "maciek" ) );
      //textblock.Foreground = new SolidColorBrush( Colors.Green );
      //textblock.FontFamily = new FontFamily( "Arial" );
      //Material material = new DiffuseMaterial( new VisualBrush( textblock ) );

ImageBrush imageBrush = new ImageBrush();
imageBrush.ImageSource = new BitmapImage(
        new Uri( @".\maciej-progtech-wpf-3d-light-sun.jpg", UriKind.Relative ) );
imageBrush.TileMode = TileMode.Tile;
imageBrush.Viewport = ( (Rect)new RectConverter().ConvertFromString( "0,0,0.5,0.5" ) );
Material material = new DiffuseMaterial( imageBrush );

      //Material material = new DiffuseMaterial(new SolidColorBrush( Colors.Blue ) );
      //Material material2 = new SpecularMaterial
      //  ( new SolidColorBrush( Colors.DarkKhaki ), 0.1 );
      //Material material2 = new EmissiveMaterial
      //  ( new SolidColorBrush( Colors.DarkKhaki ) );
      MaterialGroup materialgroup = new MaterialGroup();
      materialgroup.Children.Add( material );
      //mg.Children.Add( material2 );


//ModelVisual3D mv3d = new ModelVisual3D();
////mv3d.Content = CreateTetraederModel3DGroup( 0, 0, 0, 2, 2, 2 );
//mv3d.Content = CreateCubeModel3DGroup( -5, 0, 0, 4, 4, 4,materialgroup );
////mv3d.Content = CreateTriangleModel( new Point3D( 2, 0, 0 ), new Point3D( 0, 2, 0 ), new Point3D( 0, 0, 2 ) );
////mv3d.Content = CreateTriangleModel( new Point3D( 0, 2, 0 ), new Point3D(2, 0, 0 ), new Point3D( 0, 0, 2 ) );
//this.mainViewport.Children.Add( mv3d );
//ModelVisual3D mv3d_2 = new ModelVisual3D();
//mv3d_2.Content = CreateTetraederModel3DGroup( 5, 0, 0, 4, 4, 4,materialgroup );
////mv3d_2.Content = CreateCubeModel3DGroup( 0, 0, 0, 4, 4, 4 );
////mv3d.Content = CreateTriangleModel( new Point3D( 2, 0, 0 ), new Point3D( 0, 2, 0 ), new Point3D( 0, 0, 2 ) );
////mv3d.Content = CreateTriangleModel( new Point3D( 0, 2, 0 ), new Point3D(2, 0, 0 ), new Point3D( 0, 0, 2 ) );
//this.mainViewport.Children.Add( mv3d_2 );

    }
  }
}
